home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-17 | 54.1 KB | 1,910 lines | [TEXT/MPS ] |
- /*
- * This file has been changed from the original MacApp 3.1.1
- * to support the metrowerks CodeWarrior compilers C/C++ 1.1.1.
- * These changes are known *not* to work with earlier versions
- * of CodeWarrior. Every attempt though has been made to to keep
- * this file compatible with other development environments.
- *
- * Mark Anderson
- * metrowerks
- * 9/16/94
- *
- */
-
- //----------------------------------------------------------------------------------------
- // UMacAppGlobals.cp
- // Copyright © 1984-1994 by Apple Computer Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- #ifndef __ULIST__
- #include <UList.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef __EDITIONS__
- #include <Editions.h>
- #endif
-
- #ifndef __UAPPLEEVENTS__
- #include <UAppleEvents.h>
- #endif
-
- #ifndef __UEVENT__
- #include <UEvent.h>
- #endif
-
- #ifndef __UCOMMAND__
- #include <UCommand.h>
- #endif
-
- #ifndef __UDESIGNATOR__
- #include <UDesignator.h>
- #endif
-
- #ifndef __UEVENTHANDLER__
- #include <UEventHandler.h>
- #endif
-
- #ifndef __UAPPLICATION__
- #include <UApplication.h>
- #endif
-
- #ifndef __UDOCUMENT__
- #include <UDocument.h>
- #endif
-
- #ifndef __UFILEBASEDDOCUMENT__
- #include <UFileBasedDocument.h>
- #endif
-
- #ifndef __UPRINTHANDLER__
- #include <UPrintHandler.h>
- #endif
-
- #ifndef __BALLOONS__
- #include <Balloons.h>
- #endif
-
- #ifndef __UVIEW__
- #include <UView.h>
- #endif
-
- #ifndef __USTREAM__
- #include <UStream.h>
- #endif
-
- #ifndef __UADORNERS__
- #include <UAdorners.h>
- #endif
-
- #ifndef __UWINDOW__
- #include <UWindow.h>
- #endif
-
- #ifndef __CONTROLS__
- #include <Controls.h>
- #endif
-
- #ifndef __UCONTROL__
- #include <UControl.h>
- #endif
-
- #ifndef __USCROLLER__
- #include <UScroller.h>
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- #ifndef __UERRORMGR__
- #include <UErrorMgr.h>
- #endif
-
- #ifndef __UMEMORY__
- #include <UMemory.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __UBUSYCURSOR__
- #include <UBusyCursor.h>
- #endif
-
- #ifndef __UDEBUG__
- #include <UDebug.h>
- #endif
-
- #ifndef __UDEPENDENCIES__
- #include <UDependencies.h>
- #endif
-
- #ifndef __MENUS__
- #include <Menus.h>
- #endif
-
- #ifndef __UMENUMGR__
- #include <UMenuMgr.h>
- #endif
-
- #ifndef __SCRAP__
- #include <Scrap.h>
- #endif
-
- #ifndef __UCLIPBOARDMGR__
- #include <UClipboardMgr.h>
- #endif
-
- #ifndef __UDESKSCRAPVIEW__
- #include <UDeskScrapView.h>
- #endif
-
- #ifndef __USYNCHSCROLLER__
- #include <USynchScroller.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <Script.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __OSEVENTS__
- #include <OSEvents.h>
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- #ifndef __STDLIB__
- #include <stdlib.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- //----------------------------------------------------------------------------------------
- #if qPowerPC && !defined(__MWERKS__)
- QDGlobals qd;
- #endif
-
- Boolean gCouldPrint;
-
- TDynamicArray* gSignatures;
-
- TextStyle gSystemStyle;
- TextStyle gApplicationStyle;
- TextStyle gApplicationStyle9;
-
- WindowPtr gWorkPort;
-
- RgnHandle gTemporaryRegion = NULL;
-
- RgnHandle CTemporaryRegion::fCachedRgn = NULL;
-
- NMRecPtr gNotificationPtr = NULL;
-
- ModalFilterYDProcPtr gModalFilterYDProcPtr = MacAppStandardFileFilter;
-
- #if qDebug
- Boolean gBusyTemporaryRegion = false;
- CStr255 gUsedBy = "";
- #endif
-
- FailInfo pFi;
-
- //========================================================================================
- // CLASS PatchExitToShell
- //========================================================================================
- #pragma segment MAGlobalsRes
-
- typedef pascal void (*ExitToShellType)(void);
-
- enum
- {
- uppExitToShellProcInfo = kPascalStackBased
- };
-
- #if USESROUTINEDESCRIPTORS
- typedef UniversalProcPtr ExitToShellUPP;
-
- #define CallExitToShellProc(userRoutine) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppExitToShellProcInfo)
- #define NewExitToShellProc(userRoutine) \
- (ExitToShellUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppExitToShellProcInfo, GetCurrentISA())
- #else
- typedef ProcPtr ExitToShellUPP;
-
- #define CallExitToShellProc(userRoutine) \
- (*(userRoutine))()
- #define NewExitToShellProc(userRoutine) \
- (ExitToShellUPP)(userRoutine)
- #endif
-
- class PatchExitToShell : public TrapPatch
- {
- public:
- void Install(ExitToShellType routine);
- void CallInherited(void);
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MAInit
-
- void PatchExitToShell::Install(ExitToShellType routine)
- {
- patchRoutine = NewExitToShellProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_ExitToShell, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void PatchExitToShell::CallInherited(void)
- {
- CallExitToShellProc((ExitToShellType) oldTrapAddr);
- }
-
- //--------------------------------------------------------------------------------------------------
-
- PatchExitToShell pETSPatch;
-
- //========================================================================================
- // GLOBAL Functions
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // GetAlertButtonTitle: Retrieve the title of the button control. If itemNo isn't a
- // button, then return ''.
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void GetAlertButtonTitle(DialogPtr theDialog,
- short itemNo,
- CStr255& theTitle)
- {
- short itemType;
- Handle item;
- Rect box;
-
- theTitle = "";
- GetDialogItem(theDialog, itemNo, &itemType, &item, &box);
- if (itemType == (ctrlItem + btnCtrl))
- GetControlTitle((ControlHandle)item, theTitle);
- } // GetAlertButtonTitle
-
- //----------------------------------------------------------------------------------------
- // DoAlertKeyDown: Handle a keypress that has been mapped to one of the button controls.
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void DoAlertKeyDown(DialogPtr theDialog, short itemNo)
- {
- short itemType;
- Handle item;
- Rect box;
- long finalTicks;
-
- GetDialogItem(theDialog, itemNo, &itemType, &item, &box);
- if (itemType == (ctrlItem + btnCtrl))
- {
- // this code gives visual feedback
- HiliteControl((ControlHandle)item, inButton); // hilite the button
- Delay(8, &finalTicks); // delay for 8 ticks
- HiliteControl((ControlHandle)item, 0); // stop hiliting the button
- }
- } // DoAlertKeyDown
-
- //----------------------------------------------------------------------------------------
- // CompareAlertKeysToItem: Compares the buffered multi-byte chars to the first character
- // of each button title 1st button in alert (by convention == "OK"). 2nd button in alert
- // (by convention == "Cancel"). 3rd button in alert (by convention == "No")
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- Boolean CompareAlertKeysToItem(DialogPtr theDialog,
- CStr31& theChars,
- short& itemHit)
- {
- CStr255 title;
-
- GetAlertButtonTitle(theDialog, ok, title);
- if (CompareMultiByteChars(theChars, title, false))
- {
- itemHit = ok;
- return true;
- }
-
- GetAlertButtonTitle(theDialog, cancel, title);
- if (CompareMultiByteChars(theChars, title, false))
- {
- itemHit = cancel;
- return true;
- }
-
- GetAlertButtonTitle(theDialog, kNoButton, title);
- if (CompareMultiByteChars(theChars, title, false))
- {
- itemHit = kNoButton;
- return true;
- }
- return false;
- } // CompareAlertKeysToItem
-
- //----------------------------------------------------------------------------------------
- // DrawDefaultProc: Draw the thick rounded rectangle around the default button
- // (Imported to MacApp from Ponnuki by GA)
- //
- // This routine uses Keith Rollin's algorithm, as presented in the USENET Guide to
- // Programming the Macintosh. I have modified the basic algorithm only slightly--I add
- // two to the calculated 'buttonOval' value. This gets better results, particularly for
- // buttons of the default size (18 points).
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void DrawDefaultProc(DialogPtr dlog)
- {
- short defaultButton;
-
- // Don't call GetDialogItem if the default button # has a strange value
- defaultButton = ((DialogPeek)dlog)->aDefItem;
- if( defaultButton > 0 )
- {
- GrafPtr savePort;
- short type = 0;
- ControlHandle buttonHandle = NULL;
- CRect outlineBox;
-
- GetPort(&savePort);
- SetPort( dlog );
-
- GetDialogItem(dlog, defaultButton, &type, (Handle *) &buttonHandle, outlineBox);
- InsetRect(outlineBox,-4,-4);
-
- // Don't draw the bold outline around the default button
- // unless it really is a button
- if( type == ctrlItem + btnCtrl )
- {
- PenState saveState;
- short buttonOval;
-
- GetPenState( &saveState );
-
- // We want to draw the thick line with a normal
- // pen pattern that is 3 pixels wide
- PenNormal();
- PenSize(3,3);
-
- // If the button we are outlining is disabled,
- // draw the outline with a gray pattern.
- if( (*buttonHandle)->contrlHilite == 255 )
- {
- PenPat(&qd.gray);
- }
-
- // Calculate the curvature to use and draw the thick line
- buttonOval = 2 + (outlineBox.bottom - outlineBox.top) / 2;
- FrameRoundRect(outlineBox,buttonOval,buttonOval);
-
- SetPenState( &saveState );
- }
- SetPort(savePort);
- }
- } // DrawDefaultProc
-
- //----------------------------------------------------------------------------------------
- // MinimalAlertFilter: This is the minimally-functional alert filter that MacApp uses
- // in cases where gApplication has not yet been initialized. TApplication.AlertFilter
- // calls this filter as well.
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- pascal Boolean MinimalAlertFilter(DialogPtr theDialog,
- EventRecord& theEvent,
- short& itemHit)
- {
- Boolean returnValue = false;
-
- switch( theEvent.what )
- {
- case updateEvt:
- {
- if (((DialogPtr)theEvent.message) == theDialog)
- {
- DrawDefaultProc(theDialog);
- }
- break;
- }
-
- case keyDown:
- {
- unsigned char theChar = (unsigned char)(((theEvent.message) & charCodeMask));
-
- if ((theChar == chEnter) || (theChar == chReturn))
- {
- itemHit = ((DialogPeek)theDialog)->aDefItem;
- DoAlertKeyDown(theDialog, itemHit);
- returnValue = true;
- }
- else if ( (theChar == '`') || (theChar == chEscape) || ((theChar == '.') && (theEvent.modifiers & cmdKey)))
- {
- DoAlertKeyDown(theDialog, cancel);
- itemHit = cancel;
- returnValue = true;
- }
-
- break;
- }
- }
-
- return returnValue;
- } // MinimalAlertFilter
-
- //----------------------------------------------------------------------------------------
- // MacAppAlertFilter:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- pascal Boolean MacAppAlertFilter(DialogPtr theDialog,
- EventRecord& theEvent,
- short& itemHit)
- {
- if (gApplication)
- return gApplication->AlertFilter(theDialog, theEvent, itemHit);
- else
- return MinimalAlertFilter(theDialog, theEvent, itemHit);
- } // MacAppAlertFilter
-
- //----------------------------------------------------------------------------------------
- // MacAppAppleEventIdleProc:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- pascal Boolean MacAppAppleEventIdleProc(EventRecord& theEventRecord,
- long& sleepTime,
- RgnHandle& mouseRgn)
- {
- if (gApplication)
- return gApplication->AppleEventIdleProc(theEventRecord, sleepTime, mouseRgn);
- else
- return false;
- } // MacAppAppleEventIdleProc
-
- //----------------------------------------------------------------------------------------
- // MacAppStandardFileFilter:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- pascal Boolean MacAppStandardFileFilter(DialogPtr theDialog,
- EventRecord* theEvent,
- short* itemHit,
- void *yourDataPtr)
- {
- if (gApplication)
- return gApplication->StandardFileFilter(theDialog, *theEvent, *itemHit, yourDataPtr);
- else
- return false;
- } // MacAppStandardFileFilter
-
- //----------------------------------------------------------------------------------------
- // ApplicationBeep:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void ApplicationBeep()
- {
- if (gApplication)
- gApplication->Beep(2);
- else
- SysBeep(2);
- } // ApplicationBeep
-
- //----------------------------------------------------------------------------------------
- // CleanupMacApp:
- //----------------------------------------------------------------------------------------
- #pragma push
- #pragma trace off
-
- #pragma segment MAGlobalsRes
-
- void CleanupMacApp(void)
- {
- SetResLoad(true); // Make sure segments can load
-
- pETSPatch.UnpatchTrap(); // Guaranteed not to fail
-
- if (gApplication)
- gApplication->Terminate();
-
- gBusyCursor = (TBusyCursor *)FreeIfObject(gBusyCursor);
-
- if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr)
- AEDisposeDesc(&gServerAddress);
-
- if (gTopHandler)
- gTopHandler->Success(); // Remove the outermost failure handler
-
- #if qDebug
- DebugTerminate();
- #endif
-
- UnpatchAll();
-
- gApplication = (TApplication*) FreeIfObject(gApplication);
- } // CleanupMacApp
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // ExitToShellCleanupMacApp:
- //----------------------------------------------------------------------------------------
- #pragma push
- #pragma trace off
-
- #pragma segment MAGlobalsRes
-
- pascal void ExitToShellCleanupMacApp(void)
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- ExitToShellType oldTrapAddr = (ExitToShellType) pETSPatch.GetOldTrapAddr();
- CleanupMacApp();
- CallExitToShellProc(oldTrapAddr);
-
- SetA5(OldA5);
- } // ExitToShellCleanupMacApp
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // DoneWithTemporaryRegion: Indicates that gTemporaryRegion is no longer in use. Call this
- // only if qDebug is true.
- //----------------------------------------------------------------------------------------
- #if qDebug
- #pragma segment MADebug
-
- void DoneWithTemporaryRegion()
- {
- if (!gBusyTemporaryRegion)
- ProgramBreak("DoneWithTemporaryRegion called, but gTemporaryRegion is not locked");
- gBusyTemporaryRegion = false;
- gUsedBy = "";
- SetEmptyRgn(gTemporaryRegion);
- } // DoneWithTemporaryRegion
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // EnterDebugger:
- //----------------------------------------------------------------------------------------
- #if qDebug
- #pragma segment MADebug
-
- void EnterDebugger(Boolean entering)
- {
- if (gBusyCursor)
- gBusyCursor->Activate(!entering);
- } // EnterDebugger
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // ExitMacApp:
- //----------------------------------------------------------------------------------------
- #pragma segment MATerminate
-
- void ExitMacApp()
- {
- ExitToShell();
- // patch will call CleanupMacApp
-
- } // ExitMacApp
-
- //----------------------------------------------------------------------------------------
- // FreeIfWMgrWindow:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- WindowPtr FreeIfWMgrWindow(WindowPtr w, Boolean dispose)
- {
- if (w)
- {
- // If the window is visible, hide it first so
- // that the proper activate and deactivate events are sent.
- WindowPeek wPeek = (WindowPeek)w;
- if (wPeek->visible)
- MAHideWindow(w);
-
- if (dispose)
- {
- if (w == qd.thePort) // Only need to invalidate focus if freed window is the current port
- {
- if (gApplication)
- gApplication->InvalidateFocus();
- SetPort(gWorkPort);
- }
- DisposeWindow(w);
- }
- else
- CloseWindow(w);
- }
- return NULL; // convenience to caller
- } // FreeIfWMgrWindow
-
- //----------------------------------------------------------------------------------------
- // GetNewCenteredDialog:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- DialogPtr GetNewCenteredDialog(ResNumber dialogID,
- Ptr dStorage,
- WindowPtr behind)
- {
- DialogTHndl dlogTemplate;
-
- SetCursor(&(qd.arrow));
-
- if (gApplication)
- gApplication->InvalidateMouseRegions();
-
- dlogTemplate = (DialogTHndl)GetResource('DLOG', dialogID);
- if (dlogTemplate)
- {
- CenterRectOnScreen(((CRect &) (*dlogTemplate)->boundsRect), true, true, true);
- return GetNewDialog(dialogID, dStorage, behind);
- }
- else
- {
- SysBeep(2); // At least give some indication
- #if qDebug
- CStr255 theString;
- ConcatNumber("Unable to find ‘DLOG’ resource ", dialogID, theString);
- ProgramBreak(theString);
- #endif
-
- }
- return NULL;
- } // GetNewCenteredDialog
-
- //----------------------------------------------------------------------------------------
- // GetTextStyleFontInfo: Really a utility, but the gWorkPort isn't reachable from
- // UMacAppUtilities
- //----------------------------------------------------------------------------------------
- #pragma segment MAUtilitiesRes
-
- void GetTextStyleFontInfo(const TextStyle& theTextStyle,
- FontInfo& theFontInfo,
- short& theFontHeight)
- {
- GrafPtr savedPort;
-
- GetPort(&savedPort);
- SetPort(gWorkPort);
- SetPortTextStyle(theTextStyle);
- theFontHeight = MAGetFontInfo(theFontInfo);
- SetPort(savedPort);
- } // GetTextStyleFontInfo
-
- //----------------------------------------------------------------------------------------
- // DoRealInitToolBox:
- //----------------------------------------------------------------------------------------
- #pragma push
- // Needs to universal code
- #pragma processor 68000
- #pragma segment MAMiniInit
-
- void DoRealInitToolBox()
- {
- // -1 == 0xFFFFFFFF, the largest 32 bit address. Our routine StripLong uses a
- // pre-stripped address gStrippedAddress to avoid the yucky MPW glue. (NOTE: need
- // gStrippedAddress in DefineConfiguration.)
- gStrippedAddress = StripAddress((Ptr) - 1);
-
- // Find out just what kind of environment we're dealing with here
- DefineConfiguration(gConfiguration);
-
- // Are we background only? If so, bail out...this isn't yet supported by the code.
- if (!gConfiguration.isOnlyBackground)
- {
- // init the toolbox managers
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows(); // creates non-relocatable for the WM port
-
- // _DON'T_ flush disk-inserted or os events or you'll be sorry!
- FlushEvents(everyEvent - diskMask - osMask, 0);
- SetEventMask(everyEvent); // allow us to get keyup events too.
-
- InitMenus();
- TEInit();
- InitDialogs(NULL);
-
- CursHandle aCursHandle = GetCursor(watchCursor); // Watch should be in system
- // file, but just in case…
-
- InitCursor();
- if (aCursHandle)
- SetCursor(*aCursHandle); // Change cursor to watch
-
- // The refnum where the application's resources should be found
- gApplicationRefNum = CurResFile();
-
- gToolBoxInitialized = true;
- }
- else
- {
- #if qDebug
- DebugStr((StringPtr)"\pBackground-only apps not supported");
- #endif
- ExitToShell();
- }
- } // DoRealInitToolBox
-
- #pragma pop
-
- extern pascal void _DataInit(); // Routine in the A5 globals initializer
-
- //----------------------------------------------------------------------------------------
- // FailedInitToolBox: This procedure is intended to be in "Main" which is already loaded
- //----------------------------------------------------------------------------------------
- #pragma push
- // Needs to universal code
- #pragma processor 68000
- #pragma segment Main
-
- void FailedInitToolBox()
- {
- #if qDebug
- DebugStr((StringPtr)"\pNot enough room to initialize ToolBox managers");
- #endif
- ExitToShell();
- } // FailedInitToolBox
-
- //----------------------------------------------------------------------------------------
- // InitToolBox:
- //----------------------------------------------------------------------------------------
- void InitToolBox()
- {
- const short kBreathingRoom = 1024; // Amount of heap space needed for init
- Size totalSize = 0;
- Size contigSize = 0;
- Handle h = NULL;
-
- #if !qPowerPC
- // the heap and stack don't overlap. So there's enough room to init the managers. Make
- // sure that the MAMiniInit Segment can be loaded and that there's still a little Room
- // after that. */
-
- #ifndef __MWERKS__
- UnloadSeg(&_DataInit); // Toss some ballast
- #endif
-
- // "MAMain" this is MacApp's own code that must be resident even before/ during the
- // UMemory startup. GetNamedResource will call RsrvMem which locates the handle as low
- // in memory as possible. We will then lock it there just like "Main". In order for
- // this to work correctly the build system will have to have set the locked bit on the
- // MAMain resource.
- #ifndef __MWERKS__
- h = GetNamedResource('CODE', "\pMAMain");
- #else
- h = GetNamedResource('CODE', "\pMain");
- #endif
- if (h)
- HNoPurge(h);
- else
- FailedInitToolBox();
-
- h = GetNamedResource('CODE', "\pMAMiniInit");
- if (h)
- HNoPurge(h); // don't let it get squished out of the heap when the grow zone
- // might get called below. However, since it is not locked it will
- // float up to the top of the heap when it is entered at
- // DoRealInitToolBox.
-
- else
- FailedInitToolBox();
- #endif
-
- // Attempt to ensure that there is going to be kBreathingRoom bytes available in the
- // heap so that when the actual toolbox managers are initialized there is a
- // significantly reduced chance that they will express their displeasure with us
- // through SysErr -25 or -2. If the space is not currently available in the zone as
- // shown by PurgeSpace then attempting to allocate it will let growzoneproc operate
- // and grow the zone a little, as necessary. If, after that, we haven't been able to
- // get the breathing room we desire then just give up and fade silently away. (Like
- // the old soldier, not the old executive).
-
- PurgeSpace(&totalSize, &contigSize);
-
- if (totalSize >= kBreathingRoom)
- DoRealInitToolBox();
- else
- {
- h = NewHandle(kBreathingRoom);
- if (h != NULL) // get the grow space
- {
- DisposeHandle(h);
- DoRealInitToolBox();
- }
- else
- FailedInitToolBox(); // Give up
- }
- } // InitToolBox
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // ValidateConfiguration:
- //----------------------------------------------------------------------------------------
- #pragma push
- // Needs to universal code
- #pragma processor 68000
- #pragma segment MAMiniInit
-
- Boolean ValidateConfiguration(const Configuration& theConfiguration)
-
- {
- Boolean isSupported = true;
-
- // Run the gauntlet of support tests using the conditionally set constants. If any
- // single test fails then the app is considered unsupported on this machine.
-
- // Required minimums
- isSupported &= theConfiguration.hasROM128K;
- isSupported &= theConfiguration.hasScriptManager;
- isSupported &= theConfiguration.hasHierarchicalMenus;
- isSupported &= theConfiguration.hasStyleTextEdit;
- isSupported &= theConfiguration.hasWaitNextEvent;
-
- // Minimum system version
- isSupported &= theConfiguration.systemVersion >= 0x605;
-
- // Optionally required
- if (qNeedsColorQD)
- isSupported &= theConfiguration.hasColorQD;
-
- if (qNeedsMC68020)
- isSupported &= ((theConfiguration.processor != gestalt68000) && (theConfiguration.processor != gestalt68010));
-
- if (qNeedsMC68030)
- isSupported &= ((theConfiguration.processor != gestalt68000) && (theConfiguration.processor != gestalt68010) && (theConfiguration.processor != gestalt68020));
-
- if (qNeedsMC68040)
- isSupported &= ((theConfiguration.processor != gestalt68000) && (theConfiguration.processor != gestalt68010) && (theConfiguration.processor != gestalt68020)
- && (theConfiguration.processor != gestalt68030));
-
- if (qNeedsFPU)
- isSupported &= theConfiguration.hasFPU;
-
-
- // System 7.0 Support
- if (qNeedsSystem7)
- isSupported &= theConfiguration.systemVersion >= 0x700;
-
- if (qNeedsAppleEventMgr)
- isSupported &= theConfiguration.hasAppleEventMgr;
-
- if (qNeedsEditionMgr)
- isSupported &= theConfiguration.hasEditionMgr;
-
- if (qNeedsHelpMgr)
- isSupported &= theConfiguration.hasHelpMgr;
-
- if (qNeedsAliasMgr)
- isSupported &= theConfiguration.hasAliasMgr;
-
- if (qNeedsFolderMgr)
- isSupported &= theConfiguration.hasFolderMgr;
-
- if (qNeedsProcessMgr)
- isSupported &= theConfiguration.hasProcessMgr;
-
- // skanky hack under A/UX to ensure that all app's are pulled to front early on
-
- if (theConfiguration.hasAUX)
- PullApplicationToFront();
-
- return isSupported;
- } // ValidateConfiguration
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // MAGestaltAttribute:
- //----------------------------------------------------------------------------------------
- #pragma push
- // Needs to universal code
- #pragma processor 68000
- #pragma segment Main
-
- Boolean MAGestaltAttribute(OSType itsAttr, short itsBit)
- {
- long response;
-
- return (Gestalt(itsAttr, &response) == noErr) && (((response >> itsBit) & 1) != 0);
-
- } // MAGestaltAttribute
-
-
- //----------------------------------------------------------------------------------------
- // DefineConfiguration:
- //----------------------------------------------------------------------------------------
- #pragma segment Main
-
- void DefineConfiguration(Configuration& theConfiguration)
- {
- const short mDesktopBus = 0x0400;
-
- OSErr err;
- long response;
-
- err = Gestalt(gestaltVersion, &response);
- theConfiguration.environsVersion = (short)response;
-
- err = Gestalt(gestaltMachineType, &response);
- theConfiguration.machineType = (short)response;
-
- theConfiguration.hasROM128K = theConfiguration.machineType >= gestaltMac512KE;
- if (theConfiguration.hasROM128K)
- theConfiguration.hasHFS = true;
- else
- theConfiguration.hasHFS = LMGetFSFCBLen() > 0;
-
- err = Gestalt(gestaltSystemVersion, &response);
- theConfiguration.systemVersion = (short)response;
-
- err = Gestalt(gestaltProcessorType, &response);
- theConfiguration.processor = (short)response;
-
- err = Gestalt(gestaltFPUType, &response);
- theConfiguration.hasFPU = response != gestaltNoFPU;
-
- err = Gestalt(gestaltQuickdrawVersion, &response);
- theConfiguration.hasColorQD = response != gestaltOriginalQD;
-
- err = Gestalt(gestaltQuickdrawVersion, &response);
- theConfiguration.has32BitQD = theConfiguration.hasColorQD && (response != gestalt8BitQD);
-
- err = Gestalt(gestaltKeyboardType, &response);
- theConfiguration.keyboardType = (short)response;
-
- err = Gestalt(gestaltAppleTalkVersion, &response);
- theConfiguration.atDrvrVersNum = (short)response;
-
- theConfiguration.hasSCSI = MAGestaltAttribute(gestaltHardwareAttr, gestaltHasSCSI);
-
- err = Gestalt(gestaltAUXVersion, &response);
- theConfiguration.hasAUX = response != 0;
-
- err = Gestalt(gestaltScriptMgrVersion, &response);
- theConfiguration.hasScriptManager = theConfiguration.hasROM128K && (response != 0);
-
- theConfiguration.hasTempMem = MAGestaltAttribute(gestaltOSAttr, gestaltTempMemSupport);
-
- err = Gestalt(gestaltTextEditVersion, &response);
- theConfiguration.teVersion = response;
-
- theConfiguration.hasDesktopBus = (LMGetHWCfgFlags() & mDesktopBus) > 0;
-
- theConfiguration.hasHierarchicalMenus = theConfiguration.hasROM128K && TrapExists(_PopUpMenuSelect);
-
- theConfiguration.hasStyleTextEdit = theConfiguration.systemVersion >= 0x600;
- theConfiguration.hasSoundManager = theConfiguration.hasROM128K && TrapExists(_SndDoCommand);
- theConfiguration.hasWaitNextEvent = theConfiguration.hasROM128K && TrapExists(_WaitNextEvent);
-
- // System 7.0 support
- theConfiguration.hasAppleEventMgr = MAGestaltAttribute(gestaltAppleEventsAttr, gestaltAppleEventsPresent);
- theConfiguration.hasEditionMgr = MAGestaltAttribute(gestaltEditionMgrAttr, gestaltEditionMgrPresent);
- theConfiguration.hasHelpMgr = MAGestaltAttribute(gestaltHelpMgrAttr, gestaltHelpMgrPresent);
- theConfiguration.hasAliasMgr = MAGestaltAttribute(gestaltAliasMgrAttr, gestaltAliasMgrPresent);
- theConfiguration.hasFolderMgr = MAGestaltAttribute(gestaltFindFolderAttr, gestaltFindFolderPresent);
- theConfiguration.hasPopupCDEF = MAGestaltAttribute(gestaltPopupAttr, gestaltPopupPresent);
- theConfiguration.hasTrueType = MAGestaltAttribute(gestaltFontMgrAttr, gestaltOutlineFonts);
-
- // set default values for Process Manager-related items
- theConfiguration.hasProcessMgr = false;
- theConfiguration.isOnlyBackground = false;
- theConfiguration.isHighLevelEventAware = false;
-
- // ask process mgr for several values
- if (MAGestaltAttribute(gestaltOSAttr, gestaltLaunchControl))
- {
- theConfiguration.hasProcessMgr = true;
-
- ProcessSerialNumber psn;
- psn.highLongOfPSN = 0;
- psn.lowLongOfPSN = kCurrentProcess;
-
- ProcessInfoRec info;
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = NULL;
- info.processAppSpec = NULL;
-
- if (GetProcessInformation(&psn, &info) == noErr)
- {
- theConfiguration.isOnlyBackground = (info.processMode & modeOnlyBackground) ? true : false;
- theConfiguration.isHighLevelEventAware = (info.processMode & modeHighLevelEventAware) ? true : false;
- }
- }
-
- theConfiguration.hasDragManager = MAGestaltAttribute('drag', 0);
- theConfiguration.hasThreadManager = MAGestaltAttribute('thds', 0);
- theConfiguration.hasAOCEToolBox = MAGestaltAttribute('oceu', 0);
- theConfiguration.hasQDGXGraphics = MAGestaltAttribute('grfx', 0);
- theConfiguration.hasQDGXPrinting = MAGestaltAttribute('pmgr', 0);
- theConfiguration.hasASLM = MAGestaltAttribute('aslm', 0);
- theConfiguration.hasCFM = MAGestaltAttribute(gestaltCFMAttr, gestaltCFMPresent);
- theConfiguration.hasTranslationManager = MAGestaltAttribute(gestaltTranslationAttr, gestaltTranslationMgrExists);
- theConfiguration.hasSpeechManager = MAGestaltAttribute(gestaltSpeechAttr, gestaltSpeechMgrPresent);
- theConfiguration.hasCustomFile = MAGestaltAttribute(gestaltStandardFileAttr, gestaltStandardFile58);
- theConfiguration.hasQuickTime = (Gestalt(gestaltQuickTime, &response) == noErr);
- theConfiguration.hasTSM = (Gestalt(gestaltTSMgrVersion, &response) == noErr);
-
- } // DefineConfiguration
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // ClearTheFPU: Essential one-time initialization
- //
- // INLINE 0x42A7, // CLR.L -(A7)
- // 0x42A7, // CLR.L -(A7)
- // 0xF21F, 0x9800; // FMOVEM (A7)+, FPCR/FPSR
- //----------------------------------------------------------------------------------------
- #if !qPowerPC
- void ClearTheFPU() = { 0x42A7, 0x42A7, 0xF21F, 0x9800 };
- #endif
-
- //----------------------------------------------------------------------------------------
- // InitUMacApp_Step1 and InitUMacApp_Step3
- //----------------------------------------------------------------------------------------
- #pragma push
- #pragma processor 68000
- // Needs to be universal code
- #pragma segment Main
- // Must be in the Main segment since all other segments get unloaded from here.
-
- void InitUMacApp_Step1()
- {
- if (!gToolBoxInitialized)
- InitToolBox();
-
- // Init the basics used by the ErrorMgr (we need this for StdAlert
- // in case ValidateConfiguration fails)
- gMacAppAlertFilter = (ProcPtr) & MacAppAlertFilter;
-
- if (ValidateConfiguration(gConfiguration)) // Make sure we can run. The programmer
- // really should have ensured this in
- // their "M" file but this is a backup
- // check just in case. After all 68000's
- // don't really like to RTD.
- {
- #if !qPowerPC
- // the main procedure is always compiled with universal code so, the FPU must be
- // reset before it is used. We could get spurious crashes or worse. Remember:
- // 2+2=4 every time!
- if (qNeedsFPU || gConfiguration.hasFPU)
- ClearTheFPU();
- #endif
- }
- else
- {
- StdAlert(phUnsupportedConfiguration);
- ExitToShell(); // leave the application pronto!
- }
- } // InitUMacApp_Step1
-
- //----------------------------------------------------------------------------------------
-
- void InitUMacApp_Step3(short callsToMoreMasters)
- {
- // Install MacApp's Memory management system
- InitUMemory(callsToMoreMasters);
-
- #if !qPowerPC
- UnloadAllSegments();
-
- // Force the init segment to be memory resident, so we can call UnloadAllSegs
- // during init
- short initSeg = GetSegNumber((ProcPtr) & DoInitUMacApp);
- #ifdef __MWERKS__
- //CW can't set up the jump table if if it has already been set up. If it's locked
- //then it's set up.
- {
- Handle seg;
- Handle GetSegResource(short segnum);
-
- seg = GetSegResource(initSeg);
- if (IsHandleLocked(seg)) // not yet locked
- (*gIsResidentSeg)[initSeg - 1] = true;
- else
- SetResidentSegment(initSeg, true);
-
- }
- #else
- SetResidentSegment(initSeg, true);
- #endif
- #endif
-
- DoInitUMacApp(); // do rest of initialization
-
- #if !qPowerPC
- SetResidentSegment(initSeg, false); // make it non-resident
- UnloadAllSegments();
- #endif
- } // InitUMacApp_Step3
-
- #pragma pop
-
- //----------------------------------------------------------------------------------------
- // DoInitUMacApp: Must be in the init segment; unloaded at start of event loop
- //----------------------------------------------------------------------------------------
- #pragma segment MAInit
-
- void DoInitUMacApp()
- {
- // Initialize runtime support for objects
- InitUObject();
- #if qDebug || qTheDebugger
- InitUDebug();
- #endif
-
- gOrthogonal[vSel] = hSel;
- gOrthogonal[hSel] = vSel;
-
- gErrorParm3 = "";
-
- // assign the global text style records from resources
- MAGetTextStyle(kSystemFontTextStyle, gSystemStyle);
- MAGetTextStyle(kApplFont12TextStyle, gApplicationStyle);
- MAGetTextStyle(kApplFont9TextStyle, gApplicationStyle9);
-
- // atexit(&CleanupMacApp);
- pETSPatch.Install(ExitToShellCleanupMacApp);
-
- // Other 1-time initialization
- gTemporaryRegion = MakeNewRgn();
-
- // Create a work port for our convenience
- if (qNeedsColorQD || gConfiguration.hasColorQD)
- gWorkPort = NewCWindow(NULL, gZeroRect, gEmptyString, false, documentProc, NULL, false, 0);
- else
- gWorkPort = NewWindow(NULL, gZeroRect, gEmptyString, false, documentProc, NULL, false, 0);
-
- {
- CRect theGrayRect((*GetGrayRgn())->rgnBBox);
-
- gStandardWindowMoveBounds = theGrayRect;
- gStandardWindowMoveBounds.Inset(CPoint(4, 4));
-
- // arbitrary minimum size; maximum size is grayRgn size minus half the title bar
- gStandardWindowSizeRect = CRect(CPoint(80, 80), theGrayRect.GetSize());
- gStandardWindowSizeRect.bottom -= 8;
-
- gStandardWindowScreenRect = theGrayRect;
- gStandardWindowScreenRect.Inset(CPoint(16, 16));
- }
-
- InitUBusyCursor();
-
- gNullPrintHandler = new TPrintHandler;
- gNullPrintHandler->IPrintHandler(NULL);
-
- gPrintHandler = gNullPrintHandler;
-
- // Create the signature lists.
- gSignatures = new TDynamicArray;
- gSignatures->IDynamicArray(kEmptyIndex, sizeof(SignatureRec));
-
- if (qTemplateViews)
- {
- // ===============================================
- // Suppress Linker dead stripping of these classes
-
- macroDontDeadStrip(TView);
- macroDontDeadStrip(TIncludeView);
- macroDontDeadStrip(TWindow);
- macroDontDeadStrip(TScrollBar);
- macroDontDeadStrip(TScrollerScrollBar);
- macroDontDeadStrip(TScroller);
-
- macroDontDeadStrip(TTracker);
- macroDontDeadStrip(TList);
-
- // ===============================================
-
- RegisterStdType("TView", kStdView);
- RegisterStdType("TView", kStdDefaultView);
- RegisterStdType("TIncludeView", kStdIncludeAt);
- RegisterStdType("TWindow", kStdWindow);
- RegisterStdType("TScrollBar", kStdScrollBar);
- RegisterStdType("TScrollerScrollBar", kStdScrollerScrollBar);
- RegisterStdType("TScroller", kStdScroller);
-
- RegisterStdType("TTracker", kStdTracker);
- RegisterStdType("TList", kStdList);
- }
-
- #if qDebug
- // The linker optimizes away the meta information for the following classes by
- // stripping the ClassInfoProc. MacApp does a SetEltType on lists containing these
- // classes which requires meta information. Suppress the optimization by doing
- // suppressing dead stripping. (See UApplication.cp)
-
- macroDontDeadStrip(TDocument);
- macroDontDeadStrip(TEvent);
- macroDontDeadStrip(TClientCommand);
- #endif
-
- InitUAdorners(); // Temporarily needed for debug window
-
- InitUMenuMgr();
- InitUClipboardMgr();
- InitUAppleEvents();
-
- // create gServerAddress
- if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr)
- {
- ProcessSerialNumber psn;
- psn.highLongOfPSN = 0;
- psn.lowLongOfPSN = kCurrentProcess;
- FailOSErr(AECreateDesc(typeProcessSerialNumber, (Ptr) &psn, sizeof(ProcessSerialNumber), &gServerAddress));
- }
-
- // initialize the pseudo-random sequence generation function
- unsigned long time;
- GetDateTime(&time);
- srand((unsigned int)time);
-
- #if qDebug
- InitUDialog();
- #endif
-
- } // DoInitUMacApp
-
- //----------------------------------------------------------------------------------------
- // InstallIfPrintHandler:
- //----------------------------------------------------------------------------------------
- #pragma segment MARes
-
- void InstallIfPrintHandler(TPrintHandler* aPrintHandler,
- TView* aView)
-
- {
- TPrintHandler * aNewPrintHandler;
-
- if ((aPrintHandler) && (aView) && (aPrintHandler != gNullPrintHandler) && (gPrintHandler != gNullPrintHandler))
- {
- aNewPrintHandler = (TPrintHandler *)aPrintHandler->Clone();// signals failure if can't clone
- aNewPrintHandler->fView = aView;
- aNewPrintHandler->SetDefaultPrintInfo();
- if (aView->fDocument)
- aView->fDocument->AttachPrintHandler(aNewPrintHandler);
- aView->AttachPrintHandler(aNewPrintHandler);
- }
- } // InstallIfPrintHandler
-
- //----------------------------------------------------------------------------------------
- // MakeNewRgn:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- RgnHandle MakeNewRgn()
- {
- RgnHandle aRgn = NewRgn();
- FailNIL(aRgn);
- return aRgn;
- } // MakeNewRgn
-
- //----------------------------------------------------------------------------------------
- // DetermineClassDesc:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOpen
-
- const ClassDesc* DetermineClassDesc(IDType signature, const ClassName& className)
- {
- if (className.IsEmpty())
- return GetClassDescFromSignature(signature);
- else
- return ClassDesc::GetClassDescFromClassName(className);
- } // DetermineClassDesc
-
- //----------------------------------------------------------------------------------------
- // GetClassDescFromSignature:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOpen
-
- const ClassDesc* GetClassDescFromSignature(IDType signature)
- {
- CArrayIterator iter(gSignatures);
-
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- {
- SignatureRecPtr aSignaturePtr = (SignatureRecPtr)gSignatures->ComputeAddress(i);
-
- if (aSignaturePtr->itsSignature == signature)
- return aSignaturePtr->itsClassDesc;
- }
- return NULL;
- } // GetClassDescFromSignature
-
- //----------------------------------------------------------------------------------------
- // NewStdObject:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOpen
-
- TObject* NewStdObject(IDType signature)
- {
- const ClassDesc* classDesc = GetClassDescFromSignature(signature);
-
- if (classDesc != NULL)
- return (TObject*)(classDesc->Call_DefaultConstructor());
- else
- {
- #if qDebug
- fprintf(stderr, "signature=‘%4s’\n", (char*) & signature);
- ProgramBreak("Unable to find class for the given signature");
- #endif
- Failure(errMissingSignature, 0);
-
- return NULL; // this statement is never executed, but defeats an xlC warning
- }
- } // NewStdObject
-
- //----------------------------------------------------------------------------------------
- // NewObjectBySignature:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOpen
-
- TObject* NewObjectBySignature(IDType signature,
- const ClassName& className)
- {
- if (className.IsEmpty())
- return NewStdObject(signature);
- else
- return ClassDesc::NewByClassName(className);
- } // NewObjectBySignature
-
- //----------------------------------------------------------------------------------------
- // FindPos:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- short FindPos(const CStr255& pattern, CStr255& source)
- {
- short i = 0;
- short j = 0;
- short position = 0;
-
- do
- {
- ++i;
- position = i;
- for (j = 1; j <= pattern.Length(); ++j)
- if (!((source[i + j - 1] == pattern[j]) && (CharByte((Ptr) & source, i + j) == 0)))
- {
- position = 0;
- break;
- }
- } while (!((position > 0) || (i >= source.Length() - pattern.Length() + 1)));
-
- return position;
- } // FindPos
-
-
- //----------------------------------------------------------------------------------------
- // ParseTitleTemplate:
- //----------------------------------------------------------------------------------------
- Boolean ParseTitleTemplate(CStr255& itsTemplate,
- short& preDocname,
- short& constTitle)
-
- {
- const CStr255 kPreDocname = "<<<";
- const short kPreSize = 3;
- const CStr255 kPostDocname = ">>>";
- const short kPostSize = 3;
-
- if (itsTemplate.IsEmpty())
- {
- preDocname = 1;
- constTitle = 0;
- }
- else
- {
- preDocname = FindPos(kPreDocname, itsTemplate);
- if (preDocname > 0)
- {
- itsTemplate.Delete(preDocname, kPreSize);
- short x = FindPos(kPostDocname, itsTemplate);
- if (x == 0)
- constTitle = preDocname - 1;
- else
- {
- itsTemplate.Delete(x, kPostSize);
- constTitle = itsTemplate.Length() - x + preDocname;
- }
- }
- }
-
- return preDocname > 0;
- } // ParseTitleTemplate
-
- //----------------------------------------------------------------------------------------
- // RegisterStdType: Register or re-register a type and a class
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void RegisterStdType(const CStr255& typeName,
- IDType signature)
- {
- CArrayIterator iter(gSignatures);
- SignatureRec itsSignatureRec;
-
- // If the name can't be found it was probably misspelled or dead-stripped
- itsSignatureRec.itsSignature = signature;
- itsSignatureRec.itsClassDesc = ClassDesc::GetClassDescFromClassName(typeName);
- if (itsSignatureRec.itsClassDesc == NULL)
- Failure(minErr, 0);
-
- // Replace or add signature as necessary
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- if (((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsSignature == signature)
- break;
-
- if (iter.More())
- *((SignatureRecPtr)(gSignatures->ComputeAddress(i))) = itsSignatureRec;
- else
- gSignatures->InsertElementsBefore(gSignatures->GetSize() + 1, &itsSignatureRec, 1);
- } // RegisterStdType
-
- //----------------------------------------------------------------------------------------
- // GetStandardType:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- IDType GetStandardType(const ClassDesc* itsClassDesc)
- {
- if (itsClassDesc != NULL)
- {
- CArrayIterator iter(gSignatures);
-
- // find signature
- for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
- if (((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsClassDesc == itsClassDesc)
- return ((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsSignature;
- }
-
- // if we get here, the class descriptor wasn't found in the table of standard signatures
- return kNoIdentifier;
- } // GetStandardType
-
- //----------------------------------------------------------------------------------------
- // SubstituteInTitle:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- Boolean SubstituteInTitle(CStr255& title,
- const CStr255& newStuff,
- short preDocname,
- short constTitle)
- {
- if (preDocname > 0)
- {
- if (constTitle == 0)
- title = newStuff;
- else
- {
- title.Delete(preDocname, title.Length() - constTitle);
- title.Insert(newStuff, preDocname);
- }
- return true;
- }
- else
- return false;
- } // SubstituteInTitle
-
- //----------------------------------------------------------------------------------------
- // UseTemporaryRegion: Call this when you are about to use gTemporaryRegion and qDebug is
- // true. Used with DoneWithTemporaryRegion will prevent you from trying to use
- // gTemporaryRegion from two places at the same time.
- //----------------------------------------------------------------------------------------
- #if qDebug
- #pragma segment MADebug
-
- void UseTemporaryRegion(const CStr255& byWhom)
- {
- if (gBusyTemporaryRegion)
- {
- fprintf(stderr, "‘%s’ is trying to lock gTemporaryRegion,", (char*)byWhom);
- fprintf(stderr, "but it is already locked by ‘%s’\n", (char*)gUsedBy);
- ProgramBreak("Error in UseTemporaryRegion");
- }
- else
- {
- gBusyTemporaryRegion = true;
- gUsedBy = byWhom;
- }
- } // UseTemporaryRegion
-
- #endif
-
-
- //========================================================================================
- // CLASS CTemporaryRegion
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::new:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void* CTemporaryRegion::operator new(size_t size)
- {
- return ::operator new(size);
- }
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::delete:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CTemporaryRegion::operator delete(void*)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::CTemporaryRegion:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- CTemporaryRegion::CTemporaryRegion()
- {
- // Simple single level cache for first cut
- // take the cached region if available otherwise make one up to give out
- if (fCachedRgn)
- {
- fRgnHandle = fCachedRgn;
- fCachedRgn = NULL;
- }
- else
- {
- fRgnHandle = MakeNewRgn();
- }
-
- // Setup the FailInfo to catch any failures while this object is in scope
- fFailInfo.Reset(); // ensure that fFailInfo is in an initial state
- fFailInfo.SetCleanupProc(CTemporaryRegion::CallCleanup, this);
- } // CTemporaryRegion::CTemporaryRegion
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::~CTemporaryRegion:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- CTemporaryRegion::~CTemporaryRegion()
- {
- this->Cleanup();
-
- Success(fFailInfo);
- } // CTemporaryRegion::~CTemporaryRegion
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::Cleanup:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- void CTemporaryRegion::Cleanup()
- {
- // return to the cache if not already full
- if (fCachedRgn)
- {
- fRgnHandle = DisposeIfRgnHandle(fRgnHandle);
- }
- else
- {
- fCachedRgn = fRgnHandle;
- fRgnHandle = NULL;
- }
- } // CTemporaryRegion::Cleanup
-
- //----------------------------------------------------------------------------------------
- // CTemporaryRegion::CallCleanup:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- /*static*/ void CTemporaryRegion::CallCleanup(void* context)
- {
- ((CTemporaryRegion*) context)->Cleanup();
- } // CTemporaryRegion::CallCleanup
-
- //========================================================================================
- // GLOBAL Procedures
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // FindProcessBySignature:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr FindProcessBySignature(OSType sig,
- ProcessSerialNumber& psn,
- FSSpec* fileSpec)
- {
- OSErr err;
-
- ProcessInfoRec info;
-
- psn.highLongOfPSN = 0;
- psn.lowLongOfPSN = kNoProcess;
- do
- {
- err= GetNextProcess(&psn);
- if( err == noErr )
- {
-
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = NULL;
- info.processAppSpec = fileSpec;
-
- err= GetProcessInformation(&psn, &info);
- }
- } while( (err == noErr) && info.processSignature != sig );
-
- if( err == noErr )
- psn = info.processNumber;
-
- return err;
- } // FindProcessBySignature
-
-
- //----------------------------------------------------------------------------------------
- // GetSysVolume:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr GetSysVolume(short& vRefNum)
- {
- OSErr theErr;
-
- if (qNeedsFolderMgr || gConfiguration.hasFolderMgr)
- {
- long dir;
-
- theErr = FindFolder(kOnSystemDisk, kSystemFolderType, false, &vRefNum, &dir);
- }
- else
- {
- SysEnvRec environment;
-
- theErr = SysEnvirons(1, &environment);
- vRefNum = environment.sysVRefNum;
- }
- return theErr;
- } // GetSysVolume
-
-
- //----------------------------------------------------------------------------------------
- // GetIndVolume:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr GetIndVolume(short index,
- short& vRefNum)
- {
- ParamBlockRec pb;
- OSErr err;
-
- pb.volumeParam.ioCompletion = NULL;
- pb.volumeParam.ioNamePtr = NULL;
- pb.volumeParam.ioVolIndex = index;
-
- err = PBGetVInfo(&pb, false);
-
- vRefNum = pb.volumeParam.ioVRefNum;
- return err;
- } // GetIndVolume
-
-
- //----------------------------------------------------------------------------------------
- // VolHasDesktopDB:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr VolHasDesktopDB(short vRefNum, Boolean& hasDesktop)
- {
- HParamBlockRec pb;
- GetVolParmsInfoBuffer info;
-
- pb.ioParam.ioCompletion = NULL;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioNamePtr = NULL;
- pb.ioParam.ioBuffer = (Ptr) & info;
- pb.ioParam.ioReqCount = sizeof(GetVolParmsInfoBuffer);
-
- OSErr err = ::PBHGetVolParmsSync(&pb);
-
- hasDesktop = (err == noErr) && ((info.vMAttrib & (1L << bHasDesktopMgr)) != 0);
-
- return err;
-
- } // VolHasDesktopDB
-
-
- //----------------------------------------------------------------------------------------
- // FindAppOnVolume:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr FindAppOnVolume(OSType sig,
- short vRefNum,
- FSSpec& thefile)
- {
- DTPBRec pb;
- OSErr err;
-
- pb.ioCompletion = NULL;
- pb.ioVRefNum = vRefNum;
- pb.ioNamePtr = NULL;
- if ((err = PBDTGetPath(&pb)) != noErr)
- return err; // Puts DT refnum into pb.ioDTRefNum
- short refNum = pb.ioDTRefNum;
-
- pb.ioCompletion = NULL;
- pb.ioDTRefNum = refNum;
- pb.ioIndex = 0;
- pb.ioFileCreator = sig;
- pb.ioNamePtr = (StringPtr) thefile.name;
- err = PBDTGetAPPLSync(&pb); // Find it!
-
- if( err == fnfErr )
- err = afpItemNotFound; // Bug in PBDTGetAPPL
- if( err )
- return err; // Returns afpItemNotFound if app wasn't found.
-
- thefile.vRefNum = vRefNum;
- thefile.parID = pb.ioAPPLParID;
- return err;
- } // FindAppOnVolume
-
-
- //----------------------------------------------------------------------------------------
- // LaunchAppByFSSpec:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr LaunchAppByFSSpec(const FSSpec& fileSpec,
- LaunchFlags launchControlFlags,
- ProcessSerialNumber& psn)
- {
- LaunchParamBlockRec pb;
- OSErr err;
- FSSpec localFSSpec = fileSpec; // so we can take its address below
-
- pb.launchBlockID = extendedBlock;
- pb.launchEPBLength = extendedBlockLen;
- pb.launchFileFlags = launchNoFileFlags;
- pb.launchControlFlags = launchControlFlags | launchNoFileFlags;
- pb.launchAppSpec = &localFSSpec;
- pb.launchAppParameters = NULL;
-
- err = LaunchApplication(&pb);
- if (err == noErr)
- psn = pb.launchProcessSN;
- return err;
- } // LaunchAppByFSSpec
-
-
- //----------------------------------------------------------------------------------------
- // LaunchBySignature:
- //----------------------------------------------------------------------------------------
- #pragma segment MAGlobalsRes
-
- OSErr LaunchBySignature(OSType sig,
- ProcessSerialNumber& psn,
- FSSpec* fileSpec,
- Boolean* launched,
- Boolean allowLaunch,
- LaunchFlags launchControlFlags)
- {
- OSErr err;
- short sysVRefNum;
-
- // First see if it's already running:
-
- if (launched)
- *launched = false;
- err = FindProcessBySignature(sig, psn, fileSpec);
-
- if (err == noErr)
- if ((launchControlFlags & launchDontSwitch) == 0)
- return SetFrontProcess(&psn); // They wanted to switch to it…
-
- if (err != procNotFound || !allowLaunch)
- return err;
-
- // Well, it's not running but it's okay to launch it. Let's have a look around:
-
- if ((err = GetSysVolume(sysVRefNum)) != noErr)
- return err; // Find boot volume
- short vRefNum = sysVRefNum; // Start search with boot volume
- short index = 0;
- do
- {
- if (index == 0 || vRefNum != sysVRefNum)
- {
- Boolean hasDesktopDB;
-
- if ((err = VolHasDesktopDB(vRefNum, hasDesktopDB)) != noErr)
- return err;
- if (hasDesktopDB)
- {
- FSSpec file;
-
- // If volume has a desktop DB,
- err = FindAppOnVolume(sig, vRefNum, file); // ask it to find app
- if (err == noErr)
- {
- // If found,
- if (fileSpec)
- *fileSpec = file;
- if (launched)
- *launched = true;
- return LaunchAppByFSSpec(file, launchControlFlags, psn); // Launch it!
- }
- else if (err != afpItemNotFound)
- return err;
- }
- }
- err = GetIndVolume(++index, vRefNum); // Else go to next volume
- } while (err == noErr); // Keep going until we run out of vols
-
- if( err==nsvErr || err==afpItemNotFound )
- err= fnfErr; // File not found on any volume
- return err;
- } // LaunchBySignature
-